package com.moussa.mike;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;


public class XMLHandler extends DefaultHandler
{
	private List<YouTubeVideo> videos;
	private boolean inEntry = false;
	private boolean inEntryTitle = false;
	//private boolean inEntryContent = false;
	private boolean inEntryAuthor = false;
	private boolean inEntryAuthorName = false;
	private boolean inEntryMediagroup = false;
	private boolean inEntryMediagroupMediacategory = false;
	//private boolean inEntryMediagroupYtduration = false;
	//private boolean inEntryGdrating = false;
	//private boolean inEntryYtstatistics = false;

	private boolean isUserQuery = false;
	private boolean inTotalResults = false;
	private boolean doCaption = true;
	private String totalCountCaption = "";
	private String totalCountNoCaption = "";

	private String title = "";
	private String urlSrc = "";
	private String author = "";
	private String categoryLabel = "";
	private String categoryName = "";
	private int duration = -1;
	private float rating = -1;
	private long viewCount = -1;
	private long favoriteCount = -1;

	private String searchUrl = null;


	public XMLHandler(String searchUrl)
	{
		super();
		videos = new ArrayList<YouTubeVideo>();
		this.searchUrl = searchUrl;//&caption=true  &author=name
	}

	public List<YouTubeVideo> ParseXML()
	{
		parseXML();

		return videos;
	}
	public int ParseXMLForCount(String author, boolean doCaption)
	{
		this.isUserQuery = true;
		this.doCaption = doCaption;
		this.author = author;
		parseXML();

		totalCountNoCaption = totalCountNoCaption.trim();
		totalCountCaption = totalCountCaption.trim();

		if (doCaption)
		{
			if (totalCountCaption.equals(""))
				return -1;
			return Integer.parseInt(totalCountCaption);
		}
		else
		{
			if (totalCountNoCaption.equals(""))
				return -1;
			return Integer.parseInt(totalCountNoCaption);
		}
	}
	private void parseXML() {
		String url = searchUrl +"&caption=";
		if (doCaption)
			url += "true";
		else
			url += "false";
		if (isUserQuery && !author.equals(""))
			url += "&author=" + author;

		BufferedReader in = null;
		try {
			HttpClient client = new DefaultHttpClient();
			HttpGet request = new HttpGet();
			request.setURI(new URI(url));
			HttpResponse response = client.execute(request);
			in = new BufferedReader
			(new InputStreamReader(response.getEntity().getContent()));

			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser sp = spf.newSAXParser();
			XMLReader xr = sp.getXMLReader();
			xr.setContentHandler(this);

			xr.parse(new InputSource(in));

			in.close();
		}
		catch (IOException e) {
			videos = null;
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			videos = null;
			e.printStackTrace();
		} catch (SAXException e) {
			videos = null;
			e.printStackTrace();
		} catch (URISyntaxException e) {
			videos = null;
			e.printStackTrace();
		}
		finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void startElement(String uri, String name, String qName, Attributes atts) {

		if (name.equals("entry") && !isUserQuery)
		{
			inEntry = true;
		}
		else if (name.equals("title") && inEntry)
		{
			inEntryTitle = true;
			//get title from chars
		}
		else if (name.equals("content") && inEntry)
		{
			//inEntryContent = true;
			urlSrc = atts.getValue("src");
		}
		else if (name.equals("author") && inEntry)
		{
			inEntryAuthor = true;
		}
		else if (name.equals("name") && inEntryAuthor)
		{
			inEntryAuthorName = true;
			//get name from chars
		}
		else if (qName.equals("media:group") && inEntry)
		{
			inEntryMediagroup = true;
		}
		else if (qName.equals("media:category") && inEntryMediagroup)
		{
			inEntryMediagroupMediacategory = true;
			categoryLabel = atts.getValue("label");
			//get Category Name from chars
		}
		else if (qName.equals("yt:duration") && inEntryMediagroup)
		{
			//inEntryMediagroupYtduration = true;
			duration = Integer.parseInt(atts.getValue("seconds"));
		}
		else if (qName.equals("gd:rating") && inEntry)
		{
			//inEntryGdrating = true;
			rating = Float.parseFloat(atts.getValue("average"));
		}
		else if (qName.equals("yt:statistics") && inEntry)
		{
			//inEntryYtstatistics = true;
			viewCount = Long.parseLong(atts.getValue("viewCount"));
			favoriteCount = Long.parseLong(atts.getValue("favoriteCount"));
		}
		else if (qName.equals("openSearch:totalResults") && isUserQuery)
		{
			inTotalResults = true;
		}
	}

	public void endElement(String uri, String name, String qName)
	throws SAXException {


		if (name.equals("entry") && !isUserQuery)
		{
			inEntry = false;
			inEntryTitle = false;
			inEntryAuthor = false;
			inEntryAuthorName = false;
			inEntryMediagroup = false;
			inEntryMediagroupMediacategory = false;

			//totalCountNoCaption = totalCountNoCaption.trim();
			//totalCountCaption = totalCountCaption.trim();
			//int totalCount = Integer.parseInt(totalCountNoCaption);
			//int totalCaptionCount = Integer.parseInt(totalCountCaption);
			videos.add(new YouTubeVideo(title, author, duration, rating, urlSrc, viewCount, favoriteCount, categoryLabel, categoryName));//,totalCaptionCount,totalCount));

			title = "";
			urlSrc = "";
			author = "";
			categoryLabel = "";
			categoryName = "";
			duration = -1;
			rating = -1;
			viewCount = -1;
			favoriteCount = -1;
		}
		else if (name.equals("title") && inEntry && !isUserQuery)
		{
			title = title.trim();
			inEntryTitle = false;
		}
		else if (name.equals("author") && inEntry && !isUserQuery)
		{
			inEntryAuthor = false;
			inEntryAuthorName = false;
		}
		else if (name.equals("name") && inEntryAuthor && !isUserQuery)
		{
			author = author.trim();
			inEntryAuthorName = false;
		}
		else if (qName.equals("media:group") && inEntry && !isUserQuery)
		{
			inEntryMediagroup = false;
			inEntryMediagroupMediacategory = false;
		}
		else if (qName.equals("media:category") && inEntryMediagroup && !isUserQuery)
		{
			categoryName = categoryName.trim();
			inEntryMediagroupMediacategory = false;
		}
		else if (qName.equals("openSearch:totalResults") && isUserQuery)
		{
			inTotalResults = false;
		}
	}


	public void characters(char ch[], int start, int length) {
		String chars = " " + (new String(ch).substring(start, start + length)).trim();

		if (inEntryMediagroupMediacategory)
			categoryName = categoryName + chars;
		else if (inEntryAuthorName)
			author = author + chars;
		else if (inEntryTitle)
			title = title + chars;
		else if (inTotalResults && isUserQuery)
		{
			if (doCaption)
				totalCountCaption = totalCountCaption + chars;
			else
				totalCountNoCaption = totalCountNoCaption + chars;
		}
	}

}
